#include <stdio.h>
#include "mpx_supt.h"
#include "mrj_supt.h"
pcb* findPCB(char*);

date_rec* dateP = NULL;
void help()
{
	printf("\n\n This is a comprehensive list of commands and how they're used.\n COMMAND: \t\t\t\t DESCRIPTION:\n");
	printf("\t dispD \t\t\t Displays current date.\n");
	printf("\t dispMPX \t\t Displays contents of directory specified. \n\t\t\t\t Displays . (current directory) by default.\n\t\t\t\t ex dispD /path/dir \n");
	printf("\t help \t\t\t Displays this help menu.\n");
	printf("\t setD \t\t\t Command used to set date. ex setD mm/dd/yyyy \n");
	printf("\t vrsn \t\t\t Displays version of MPX. \n");
	printf("\t exit \t\t\t Exits program on confirmation. ex y or n\n");

}

void version()
{
	printf("\nVersion 1.0\n\n");
}

void displayDate()
{
	sys_get_date(dateP);
	printf("\n%d/", dateP->month);
	printf("%d/", dateP->day);
	printf("%d\n\n", dateP->year);
}

void changeDate(int m, int d, int y)
{
	int valid = 1;           //date validation parameter

	if(y<0) {valid=0;}    //Year is a negative number

	if(m>12 || m<1) {valid=0;} //Month must be 1-12

	if (y%400 == 0 || (y%4 == 0 && y%100 != 0))   //Leap year
	{
		if(m==2 && d>29) {valid=0;}  //29 days in feb during leap year
	}
	
	if (!(y%400 == 0 || (y%4 == 0 && y%100 != 0)))   //Not Leap year
	{
		if(m==2 && d>28) {valid=0;}  //28 days in feb
	}

	else if((m==4 || m==6 || m==9 || m==11) && d>30) {valid=0;}//30 days

	else if((m==1 || m==3 || m==5 || m==7 || m==8
	|| m==10 || m==12) && d>31) {valid=0;}        //31 day months



	if(valid)           //Valid date, execute sys_set_date()
	{
		dateP->month = m;
		dateP->day = d;
		dateP->year = y;
		sys_set_date(dateP);
	}

	else if(valid==0)    //invalid date
	{ printf("Invalid date, please try again.\n");}
}

void displayMPX(char* dir_path)
{
		//declaring
  int error_check;
  char file_name_buf[80];
  long *file_size_p;
  file_name_buf[strlen(file_name_buf)-1]='\0';
  
  printf("dir path: %s \n", dir_path);
  //open directory specified
  if(dir_path[0]!='\n'){
	//printf("%d", sys_open_dir(dir_path));
	dir_path[strlen(dir_path)-1] = '\0';
	sys_open_dir(dir_path); //look up directory to open
	}
  else{
	//printf("%d", sys_open_dir('\0'));
	sys_open_dir('\0');
	}
 
  //do block is used to grab each mpx file, display it and look for next
  error_check = sys_get_entry(file_name_buf, 20, file_size_p);
  //printf("error=%d\n", error_check);
  while (error_check != ERR_SUP_NOENTR){
	error_check = sys_get_entry(file_name_buf, 20, file_size_p);
    printf("%s \t\t %d \n", file_name_buf, file_size_p);
	}
	
  //close directory
  sys_close_dir();
}

void terminateMPX()
{
	sys_exit();
}

void commhan()
{
	char bufC[80];
	int buf_sizeC = 80;
	int exit = 0;
	sys_req(CLEAR, TERMINAL, bufC, &buf_sizeC);

	printf("Welcome. For a list of commands type help into\nthe command prompt. After typing a command to\nthe system you will be prompted again to enter\nthe needed information. This system is NOT case\nsensitive.\n");
			
	
	while(!exit)         //run until exit command is executed
	{
		char bufWithSpaces[80];       //input with spaces
		int buf_size = 80;
		int counter = 0;
		char buf[80];
		int i;
		char array[40];
		pcb* temp;

		printf("USER> ");          //input prompt
		sys_req(READ, TERMINAL, bufWithSpaces, &buf_size);
		bufWithSpaces[strlen(bufWithSpaces)-1]='\0';

		
		
		
		for(i=0; i<buf_size; i++)                //Gets rid of spaces in input
		{
			if(bufWithSpaces[i] != ' ')
			{
				buf[counter] = bufWithSpaces[i];
				counter++;
			}
		}

		
		if(((buf[0] == 'h') || (buf[0] == 'H')) && ((buf[1] == 'e') || (buf[1] == 'E')) //help
		&& ((buf[2] == 'l') || (buf[2] == 'L')) && ((buf[3] == 'p') || (buf[3] == 'P'))
		&& (buf[4] == '\0'))
		{
			help();
		}
		
		else if(((buf[0] == 'v') || (buf[0] == 'V')) && ((buf[1] == 'r') || (buf[1] == 'R')) //vrsn
		&& ((buf[2] == 's') || (buf[2] == 'S')) && ((buf[3] == 'n') || (buf[3] == 'N'))
		&& (buf[4] == '\0'))
		{
			version();
		}
		
		else if(((buf[0] == 'c') || (buf[0] == 'C')) && ((buf[1] == 'r') || (buf[1] == 'R')) //Create PCB
		&& ((buf[2] == 'e') || (buf[2] == 'E')) && ((buf[3] == 'a') || (buf[3] == 'A'))
		&& ((buf[4] == 't') || (buf[4] == 'T')) && ((buf[5] == 'e') || (buf[5] == 'E'))
		&& ((buf[6] == 'p') || (buf[6] == 'P')) && ((buf[7] == 'c') || (buf[7] == 'C'))
		&& ((buf[8] == 'b') || (buf[8] == 'B')) && (buf[9] == '\0'))
		{
			int i, class, num, dontInsert=0;
			char* newName;
			char* pQtype;
			char queueType[1];
			buf_size=80;
			counter=0;
			//temp = allocPCB();
			//--------------------NAMING------------------------------------------------
			printf("What would you like to name this PCB?\n");
			printf(" --> ");
			sys_req(READ, TERMINAL, bufWithSpaces, &buf_size);
			bufWithSpaces[strlen(bufWithSpaces)-1]='\0';
			
			
			for(i=0; i<buf_size; i++)                //Gets rid of spaces in input
			{
				if(bufWithSpaces[i] != ' ')
				{
					buf[counter] = bufWithSpaces[i];
					counter++;
				}
			}
			strcpy(array,buf);
			newName = array;
			//temp->name = newName;
			
			
			//---------PRIORITIZING-----------------------------------------------------------
			printf("Enter the priority\n");
			printf(" --> ");
			counter=0;
			sys_req(READ, TERMINAL, bufWithSpaces, &buf_size);
			bufWithSpaces[strlen(bufWithSpaces)]='\0'; 
			
			for(i=0; i<buf_size; i++)                //Gets rid of spaces in input
			{
				if(bufWithSpaces[i] != ' ')
				{
					buf[counter] = bufWithSpaces[i];
					counter++;
				}
			}
			
			if(buf[0] != '-')  //Positive value
			{
				if((strlen(buf)-1) == 3) //convert input into a real int
				{
					num = ((int)(((buf[0])-48)*100)) + ((int)(((buf[1])-48)*10)) + (((int)(buf[2])-48));
				}
			
				else if((strlen(buf)-1) == 2) //convert input into a real int
				{
					num = ((int)(((buf[0])-48)*10)) + ((int)(((buf[1])-48)));
				}
			
				else if((strlen(buf)-1) == 1) //convert input into a real int
				{
					num = ((int)((buf[0])-48));
				}
			}
			
			else if(buf[0] == '-')  //Negative value
			{
				if((strlen(buf)-1) == 4) //convert input into a real int
				{
					num = ((int)(((buf[1])-48)*100)) + ((int)(((buf[2])-48)*10)) + (((int)(buf[3])-48));
				}
			
				else if((strlen(buf)-1) == 3) //convert input into a real int
				{
					num = ((int)(((buf[1])-48)*10)) + ((int)(((buf[2])-48)));
				}
			
				else if((strlen(buf)-1) == 2) //convert input into a real int
				{
					num = ((int)((buf[1])-48));
				}
				
				num = num*(-1);
			}
			
			if((num>(-129))&&(num<128)) //Valid priority number
			{
				//temp->priority = num;
			}
			
			else {printf("Invalid Priority"); dontInsert=1;}

			//-----------CLASSIFIED--------------------------------------------------------
			printf("Enter the class...a 1 idicates APP, while a 0 indicates SYSTEM\n");
			printf(" --> ");
			counter=0;
			sys_req(READ, TERMINAL, bufWithSpaces, &buf_size);
			printf("UUUJHBJHUHUU\n");
			bufWithSpaces[strlen(bufWithSpaces)]='\0'; 
			
			for(i=0; i<buf_size; i++)                //Gets rid of spaces in input
			{
				if(bufWithSpaces[i] != ' ')
				{
					buf[counter] = bufWithSpaces[i];
					counter++;
				}
			}
			printf("UUUJHBJHUHUU\n");
			class = ((int)((buf[0])-48));
			printf("UUUJHBJHUHUU\n");
			if((class!=1)&&(class!=0)){ dontInsert=1;}
			printf("UUUJHBJHUHUU\n");
			//temp->Pclass = class;
			
			//---------SENDING--INFO---------------------------------------------------------
			//temp = setPCB(newName,num,class);
			
			//--------------------ENQUEUEING-------------------------------------------------
			queueType[0] = 'r';
			pQtype = queueType;  //Insert in ready queue
			printf("UUUJHBJHUHUU\n");
			if(dontInsert !=1) {insertPCB(pQtype, setPCB(newName,num,class));} //Valid pcb
			
		}
		
		else if(((buf[0] == 'd') || (buf[0] == 'D')) && ((buf[1] == 'e') || (buf[1] == 'E')) //Delete PCB
		&& ((buf[2] == 'l') || (buf[2] == 'L')) && ((buf[3] == 'e') || (buf[3] == 'E'))
		&& ((buf[4] == 't') || (buf[4] == 'T')) && ((buf[5] == 'e') || (buf[5] == 'E'))
		&& ((buf[6] == 'p') || (buf[6] == 'P')) && ((buf[7] == 'c') || (buf[7] == 'C'))
		&& ((buf[8] == 'b') || (buf[8] == 'B')) && (buf[9] == '\0'))
		{
			//temp = freePCB();
		}
		
		else if(((buf[0] == 'b') || (buf[0] == 'B')) && ((buf[1] == 'l') || (buf[1] == 'L')) //Block
		&& ((buf[2] == 'o') || (buf[2] == 'O')) && ((buf[3] == 'c') || (buf[3] == 'C'))
		&& ((buf[4] == 'k') || (buf[4] == 'K')) && (buf[5] == '\0'))
		{
			printf("%d\n", temp->state);
			temp->state = 2;
			printf("%d\n", temp->state);
		}
		
		else if(((buf[0] == 'u') || (buf[0] == 'U')) && ((buf[1] == 'n') || (buf[1] == 'N')) //Unblock
		&& ((buf[2] == 'b') || (buf[2] == 'B')) && ((buf[3] == 'l') || (buf[3] == 'L'))
		&& ((buf[4] == 'o') || (buf[4] == 'O')) && ((buf[5] == 'c') || (buf[5] == 'C'))
		&& ((buf[6] == 'k') || (buf[6] == 'K'))  && (buf[7] == '\0'))
		{
			printf("%d\n", temp->state);
			temp->state = 1;
			printf("%d\n", temp->state);
		}
		
		else if(((buf[0] == 's') || (buf[0] == 'S')) && ((buf[1] == 'u') || (buf[1] == 'U')) //Suspend
		&& ((buf[2] == 's') || (buf[2] == 'S')) && ((buf[3] == 'p') || (buf[3] == 'P'))
		&& ((buf[4] == 'e') || (buf[4] == 'E')) && ((buf[5] == 'n') || (buf[5] == 'N'))
		&& ((buf[6] == 'd') || (buf[6] == 'D'))  && (buf[7] == '\0'))
		{
			printf("%d\n", temp->susp);
			temp->susp = 1;
			printf("%d\n", temp->susp);
		}
		
		else if(((buf[0] == 'r') || (buf[0] == 'R')) && ((buf[1] == 'e') || (buf[1] == 'E')) //Resume
		&& ((buf[2] == 's') || (buf[2] == 'S')) && ((buf[3] == 'u') || (buf[3] == 'U'))
		&& ((buf[4] == 'm') || (buf[4] == 'M')) && ((buf[5] == 'e') || (buf[5] == 'E'))
		&& (buf[7] == '\0'))
		{
			printf("%d\n", temp->susp);
			temp->susp = 0;
			printf("%d\n", temp->susp);
		}
		
		else if(((buf[0] == 's') || (buf[0] == 'S')) && ((buf[1] == 'e') || (buf[1] == 'E')) //Set Priority
		&& ((buf[2] == 't') || (buf[2] == 'T')) && ((buf[3] == 'p') || (buf[3] == 'P'))
		&& ((buf[4] == 'r') || (buf[4] == 'R')) && ((buf[5] == 'i') || (buf[5] == 'I'))
		&& ((buf[6] == 'o') || (buf[6] == 'O')) && ((buf[7] == 'r') || (buf[7] == 'R'))
		&& ((buf[8] == 'i') || (buf[8] == 'I')) && ((buf[9] == 't') || (buf[9] == 'T')) 
		&& ((buf[10] == 'y') || (buf[10] == 'Y')) && (buf[11] == '\0'))
		{
			int num;
			int i;
			printf("Enter new priority -> ");
			buf_size = 80;
			bufWithSpaces[0]='\0';
			buf[0]='\0';
			counter=0;
			sys_req(READ, TERMINAL, bufWithSpaces, &buf_size);
			bufWithSpaces[strlen(bufWithSpaces)]='\0'; 
			
			for(i=0; i<buf_size; i++)                //Gets rid of spaces in input
			{
				if(bufWithSpaces[i] != ' ')
				{
					buf[counter] = bufWithSpaces[i];
					counter++;
				}
			}
			
			if(buf[0] != '-')  //Positive value
			{
				if((strlen(buf)-1) == 3) //convert input into a real int
				{
					num = ((int)(((buf[0])-48)*100)) + ((int)(((buf[1])-48)*10)) + (((int)(buf[2])-48));
				}
			
				else if((strlen(buf)-1) == 2) //convert input into a real int
				{
					num = ((int)(((buf[0])-48)*10)) + ((int)(((buf[1])-48)));
				}
			
				else if((strlen(buf)-1) == 1) //convert input into a real int
				{
					num = ((int)((buf[0])-48));
				}
			}
			
			else if(buf[0] == '-')  //Negative value
			{
				if((strlen(buf)-1) == 4) //convert input into a real int
				{
					num = ((int)(((buf[1])-48)*100)) + ((int)(((buf[2])-48)*10)) + (((int)(buf[3])-48));
				}
			
				else if((strlen(buf)-1) == 3) //convert input into a real int
				{
					num = ((int)(((buf[1])-48)*10)) + ((int)(((buf[2])-48)));
				}
			
				else if((strlen(buf)-1) == 2) //convert input into a real int
				{
					num = ((int)((buf[1])-48));
				}
				
				num = num*(-1);
			}
			
			if((num>(-129))&&(num<128)) //Valid priority number
			{
				printf("%d\n",num);
				temp->priority = num;
				printf("%s: priority = %d\n", temp->name, temp->priority);
			}
				
			else {printf("Invalid Priority\n", num);}
		}
		
		else if(((buf[0] == 's') || (buf[0] == 'S')) && ((buf[1] == 'h') || (buf[1] == 'H')) //Show PCB
		&& ((buf[2] == 'o') || (buf[2] == 'O')) && ((buf[3] == 'w') || (buf[3] == 'W'))
		&& ((buf[4] == 'p') || (buf[4] == 'P')) && ((buf[5] == 'c') || (buf[5] == 'C'))
		&& ((buf[6] == 'b') || (buf[6] == 'B')) && (buf[7] == '\0'))
		{
			int i;
			char desiredName[40];
			char* pName;
			pcb* newPcb;
			buf_size=80;
			counter=0;
			bufWithSpaces[0]='\0';
			buf[0]='\0';
			printf("Enter the name of the pcb you want to see.\n");
			printf(" --> ");
			sys_req(READ, TERMINAL, bufWithSpaces, &buf_size);
			bufWithSpaces[strlen(bufWithSpaces)-1]='\0';
			
			
			for(i=0; i<buf_size; i++)                //Gets rid of spaces in input
			{
				if(bufWithSpaces[i] != ' ')
				{
					buf[counter] = bufWithSpaces[i];
					counter++;
				}
			}
			strcpy(desiredName,buf);
			pName = desiredName;
			newPcb = findPCB(pName);
		
			printf("-------------------------Key--------------------------------\n");
			printf("State: 	0 => run,  1 => ready,  2 => blocked\n");
			printf("Suspended?: 0 => NOT suspended,  0 => suspended\n");
			printf("Class: 	0 => system, 1 => app\n");
			printf("------------------------------------------------------------\n");
			printf("Name		Priority	State	Suspended?	Class	Mem_Size\n");
			printf("%s		   %d		  %d	   %d		%d	  %d\n", temp->name,temp->priority,temp->state,
			temp->susp,temp->Pclass,temp->memSize);
		}
		
		else if(((buf[0] == 's') || (buf[0] == 'S')) && ((buf[1] == 'h') || (buf[1] == 'H')) //Show All
		&& ((buf[2] == 'o') || (buf[2] == 'O')) && ((buf[3] == 'w') || (buf[3] == 'W'))
		&& ((buf[4] == 'a') || (buf[4] == 'A')) && ((buf[5] == 'l') || (buf[5] == 'L'))
		&& ((buf[6] == 'l') || (buf[6] == 'L')) && (buf[7] == '\0'))
		{
			
		}
		
		else if(((buf[0] == 's') || (buf[0] == 'S')) && ((buf[1] == 'h') || (buf[1] == 'H')) //Show Ready
		&& ((buf[2] == 'o') || (buf[2] == 'O')) && ((buf[3] == 'w') || (buf[3] == 'W'))
		&& ((buf[4] == 'r') || (buf[4] == 'R')) && ((buf[5] == 'e') || (buf[5] == 'E'))
		&& ((buf[6] == 'a') || (buf[6] == 'A')) && ((buf[7] == 'd') || (buf[7] == 'D'))
		&& ((buf[8] == 'y') || (buf[8] == 'Y')) && (buf[9] == '\0'))
		{
			
		}
		
		else if(((buf[0] == 's') || (buf[0] == 'S')) && ((buf[1] == 'h') || (buf[1] == 'H')) //Show Blocked
		&& ((buf[2] == 'o') || (buf[2] == 'O')) && ((buf[3] == 'w') || (buf[3] == 'W'))
		&& ((buf[4] == 'b') || (buf[4] == 'B')) && ((buf[5] == 'l') || (buf[5] == 'L'))
		&& ((buf[6] == 'o') || (buf[6] == 'O')) && ((buf[7] == 'c') || (buf[7] == 'C'))
		&& ((buf[8] == 'k') || (buf[8] == 'K')) && ((buf[9] == 'e') || (buf[9] == 'E'))		
		&& ((buf[10] == 'd') || (buf[10] == 'D')) && (buf[11] == '\0'))
		{
			
		}
		
		else if(((buf[0] == 'd') || (buf[0] == 'D')) && ((buf[1] == 'i') || (buf[1] == 'I')) //dispD
		&& ((buf[2] == 's') || (buf[2] == 'S')) && ((buf[3] == 'p') || (buf[3] == 'P'))
		&& ((buf[4] == 'd') || (buf[4] == 'D')) && (buf[5] == '\0'))
		{
			displayDate();
		}
		
		else if(((buf[0] == 's') || (buf[0] == 'S')) && ((buf[1] == 'e') || (buf[1] == 'E')) //setD
		&& ((buf[2] == 't') || (buf[2] == 'T')) && ((buf[3] == 'd') || (buf[3] == 'D'))
		&& (buf[4] == '\0'))
		{
			int i;
			printf("	Enter new date(mm/dd/yyyy) -> ");
			buf_size = 80;
			bufWithSpaces[0]='\0';
			buf[0]='\0';
			counter = 0;
			
			
			sys_req(READ, TERMINAL, bufWithSpaces, &buf_size);
			bufWithSpaces[strlen(bufWithSpaces)-1]='\0';         

			
			for(i=0; i<buf_size; i++)                //Gets rid of spaces in input
			{
				if(bufWithSpaces[i] != ' ')
				{
					buf[counter] = bufWithSpaces[i];
					counter++;
				}
			}
			
			if((strlen(buf)-1)!=9){printf("		Date was not in the(mm/dd/yyyy) format\n");}//invalid			
			
			else               //valid input
			{
				int month = (((int)(buf[0])-48)*10)+(((int)(buf[1])-48));         
				int day = (((int)(buf[3])-48)*10)+(((int)(buf[4])-48));
				int year = (((int)(buf[6])-48)*1000)+(((int)(buf[7])-48)*100)
					+(((int)(buf[8])-48)*10)+(((int)(buf[9])-48));
				changeDate(month, day, year);               
			}												
		}        	                                       
		
		else if(((buf[0] == 'd') || (buf[0] == 'D')) && ((buf[1] == 'i') || (buf[1] == 'I')) //dispMPX
		&& ((buf[2] == 's') || (buf[2] == 'S')) && ((buf[3] == 'p') || (buf[3] == 'P'))
		&& ((buf[4] == 'm') || (buf[4] == 'M'))  && ((buf[5] == 'p') || (buf[5] == 'P'))
		&& ((buf[6] == 'x') || (buf[6] == 'X')) && (buf[7] == '\0'))
		{
			printf("	Enter the directory -> ");
			buf_size = 80;
			sys_req(READ, TERMINAL, buf, &buf_size);
			//buf[strlen(buf)-1]='\0';
			if((strlen(buf)) == 0)
			{
				char empty[10];
				empty[0]=0;
				displayMPX(empty);
			}

			else {displayMPX(buf);}
		}

		else if(((buf[0] == 'e') || (buf[0] == 'E')) && ((buf[1] == 'x') || (buf[1] == 'X')) //exit
		&& ((buf[2] == 'i') || (buf[2] == 'I')) && ((buf[3] == 't') || (buf[3] == 'T'))
		&& (buf[4] == '\0'))
		{
			int i;
			printf("Are you sure you want to exit?\n");   //exit confirmation
			printf("	(Y/N) -> ");
			buf_size=80;
			counter=0;
			sys_req(READ, TERMINAL, bufWithSpaces, &buf_size);
			
			
			for(i=0; i<buf_size; i++)                //Gets rid of spaces in input
			{
				if(bufWithSpaces[i] != ' ')
				{
					buf[counter] = bufWithSpaces[i];
					counter++;
				}
			}
			
			if((buf[0] == 'y') || (buf[0] == 'Y')) { exit=1;}   //yes exit
			else if((buf[0] == 'n') || (buf[0] == 'N')) {exit=0;} //no don't exit
			else {printf("Invalid input, enter either a 'Y' or 'N'\n");} //wrong answer
		}

		else {printf("Unrecognized command, type help for assistance\n");}
	}
	
}